package com.wangzhen.spring.data.binding;

import com.wangzhen.spring.ioc.dependcy.entity.User;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.PropertyValues;
import org.springframework.validation.BindingResult;
import org.springframework.validation.DataBinder;

import java.util.HashMap;
import java.util.Map;

/**
 * DataBinder演示数据绑定demo
 * 1、通过DataBinder#bind方法来为某一个对象赋值；
 * 2、通过设置DataBinder的一些选项来控制赋值时的一些行为；例如当对象属性不存在时，为嵌套属性字段赋值时，设置白名单时；
 * 3、
 * @see DataBinder
 */
public class DataBinderDemo {

    public static void main(String[] args) {
        // 创建空白对象
        User user = new User();
        // 创建dataBinder
        DataBinder dataBinder = new DataBinder(user, "user");
        // 构造PropertyValues，指定name和age字段的值
        Map<String, Object> map = new HashMap<>();
        map.put("name", "zhangsan");
        map.put("age", 20);
        // DataBinder特性1：可以忽略不存在的属性
        map.put("adderss", "china");
        // DataBinder特性2：可以支持嵌套属性
        map.put("company.name", "airdoc");
        PropertyValues propertyValues = new MutablePropertyValues(map);

        // 设置选项1：是否忽略未知属性，默认true(如果设置为false不忽略，那么就会报错，因为user对象中没有address这个字段)
        //dataBinder.setIgnoreUnknownFields(false);

        // 设置选项2：是否可以自动的嵌套对象属性，默认true
        // map.put("company.name", "airdoc"); 如果自动嵌套属性设置为true，那么内部会自动创建Company对象，并调用setName方法
        // 非自动嵌套路径就需要这么设置了：  map.put("company", new Company()); map.put("company.name", "airdoc");
        // dataBinder.setAutoGrowNestedPaths(false);

        // 设置选项3：设置忽略违法属性,默认false
        // dataBinder.setIgnoreInvalidFields(true);

        // 设置选项4：设置必须需要绑定的字段
        // 在上面的propertyValues赋值中，没有给cityEnum这个字段赋值，因此让我们瞧瞧吧，程序貌似运行之后
        // 并没有输出任何异常，此时需要用到bindingResult对象,通过dataBinder.getBindingResult()获取到
        // 结果并打印就能看到错误的信息了
        dataBinder.setRequiredFields("name", "age", "cityEnum");

        // 使用bind方法绑定数据
        dataBinder.bind(propertyValues);

        System.out.println(user);

        BindingResult bindingResult = dataBinder.getBindingResult();
        System.out.println(bindingResult);
    }

}
